<?php
require_once dirname(dirname(__FILE__)) . '/config/config.php';
require_once DOCUMENT_ROOT . DIR_SHARED_DAO . "dao_user.php";
require_once DOCUMENT_ROOT . DIR_SHARED_DAO . "dao_bet_history.php";
require_once DOCUMENT_ROOT . DIR_SHARED_API . "api_general.php";
require_once DOCUMENT_ROOT . DIR_SHARED_API . "api_transaction.php";
require_once DOCUMENT_ROOT . DIR_SHARED_LIBRARIES . 'lib_redirect.php';
require_once DOCUMENT_ROOT . DIR_SHARED_LIBRARIES . 'lib_session.php';

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of api_security
 *
 * @author Thien
 */
class api_bet_calculators {
    
    public static function place_bet($username, $bet_amount, $match_id, $choice_id, $affiliate_email) {
        $dao_bet_history = new dao_bet_history();
        $dao_user = new dao_user();
        $user = $dao_user->get_by_username($username);
        if (empty($affiliate_email) && !empty($user['invite_by_user_id']) && $user['invite_by_user_id'] > 0) {
            $affiliate_profit = self::get_affiliate_commission() * $bet_amount;
            $affiliate_profit += $user['affiliate_profit'];
            $dao_user->update_affiliate_profit($user['id'], $affiliate_profit);
        }
        $dao_bet_history->save(0, $match_id, $bet_amount, $user['id'], $choice_id, $affiliate_email);
        return self::charge_with_amount($username, $bet_amount, $match_id);
    }
    
    public static function get_balance($username) {
        $dao_user = new dao_user();
        $user = $dao_user->get_by_username($username);
        return $user['balance'];
    }
    
    public static function charge_with_amount($username, $amount, $match_id) {
        $dao_user = new dao_user();
        $user = $dao_user->get_by_username($username);
        $amount_after_charge = $user['balance'] - $amount;
        $match = api_matches::get_match_by_id($match_id);
        api_transaction::spend_transaction($user['id'], 'Betting For "'.$match['name'].'" match', $amount);
        return $dao_user->update_balance($user['id'], $amount_after_charge);
    }
    
    public static function can_bet($username, $bet_amount) {
        $dao_user = new dao_user();
        $user = $dao_user->get_by_username($username);
        if ($bet_amount <= $user['balance']) {
            return TRUE;
        }
        return FALSE;
    }
    
    public static function get_all_bet_history_by_email($email) {
        $dao_bet_history = new dao_bet_history();
        $dao_user = new dao_user();
        $user = $dao_user->get_by_email($email);
        $bet_history = $dao_bet_history->get_all_by_user_id($user['id']);
        $list = array();
        foreach ($bet_history as $item) {
            $item['profit_if_win'] = self::calculate_profit_if_bet_win($item, FALSE);
            $list[count($list)] = $item;
        }
        return $list;
    }
    
    public static function get_all_bet_history_by_match_id($match_id) {
        $dao_bet_history = new dao_bet_history();
        $bet_history = $dao_bet_history->get_all_by_match_id($match_id);
        $list = array();
        foreach ($bet_history as $item) {
            $item['profit_if_win'] = self::calculate_profit_if_bet_win($item, FALSE);
            $item['total_if_win'] = $item['profit_if_win'] + $item['bet_amount'];
            $list[count($list)] = $item;
        }
        return $list;
    }
    
    public static function finalize_match($match_id, $win_choice_id) {
        if (self::only_one_player_on_match($match_id, FALSE)) {
            $dao_match = new dao_match();
            self::repay($match_id);
            $dao_match->cancel($match_id, "Only One Player.");
        } else if (self::only_bets_on_one_choice($match_id)){
            $dao_match = new dao_match();
            self::repay($match_id);
            $dao_match->cancel($match_id, "Only One or No Choice.");
        } else {
            $dao_bet_history = new dao_bet_history();
            $bet_histories = $dao_bet_history->get_all_win_bet_by_match_id($match_id, $win_choice_id);
            $list = array();
            foreach ($bet_histories as $item) {
                $item['profit_if_win'] = self::calculate_profit_if_bet_win($item, FALSE);
                $item['total_if_win'] = $item['profit_if_win'] + $item['bet_amount'];
                self::award_prize($item);
                $list[count($list)] = $item;
            }
            return $list;
        }
        
    }
    
    public static function only_one_player_on_match($match_id, $before_betting) {
        lib_session::start_session();
        $dao_bet_history = new dao_bet_history();
        $bet_histories = $dao_bet_history->get_all_by_match_id($match_id);
        if (!empty($bet_histories) && count($bet_histories) > 0) {
            if ($before_betting) {
                $bet_histories[count($bet_histories)] = ['user_id' => $_SESSION['user_info']['id']];
            }
            for ($index = 1; $index < count($bet_histories); $index++) {
                if ($bet_histories[$index]['user_id'] != $bet_histories[$index - 1]['user_id']) {
                    return FALSE;
                }
            }
        }
        return TRUE;
    }
    
    private static function only_bets_on_one_choice($match_id) {
        $dao_bet_history = new dao_bet_history();
        $count_all_bets = $dao_bet_history->count_all_by_match_id($match_id);
        $dao_match_choice = new dao_match_choice();
        $choices = $dao_match_choice->get_all_by_match_id($match_id);
        foreach ($choices as $choice) {
            $count_choice_on_bet = $dao_bet_history->count_all_with_choice_id($match_id, $choice['choice_id']);
            if ($count_choice_on_bet == $count_all_bets) {
                return TRUE;
            }
        }
        return FALSE;
    }
    
    private static function award_prize($bet_history) {
        $dao_user = new dao_user();
        $user = $dao_user->get_by_id_without_role($bet_history['user_id']);
        $match = api_matches::get_match_by_id($bet_history['match_id']);
        api_transaction::receive_transaction($bet_history['user_id'], 'Prize is awarded at "'.$match['name'].'" match', $bet_history['total_if_win']);
        return $dao_user->update_balance($bet_history['user_id'], $user['balance'] + $bet_history['total_if_win']);
    }
    
    private static function repay($match_id) {
        $dao_user = new dao_user();
        $dao_bet_history = new dao_bet_history();
        $bet_histories = $dao_bet_history->get_all_by_match_id($match_id);
        $match = api_matches::get_match_by_id($match_id);
        foreach ($bet_histories as $history) {
            $user = $dao_user->get_by_id_without_role($history['user_id']);
            api_transaction::receive_transaction($user['id'], '"'.$match['name'].'" match is canceled.', $history['bet_amount']);
            $dao_user->update_balance($history['user_id'], $user['balance'] + $history['bet_amount']);
        }
    }
    
    public static function calculate_profit_if_bet_win($bet_history, $before_betting) {
        $dao_bet_history = new dao_bet_history();
        $bet_histories = $dao_bet_history->get_all_by_match_id($bet_history['match_id']);
        $total_bet_amount = self::calculate_total_bet_amount($bet_histories);
        if ($before_betting) {
            $total_bet_amount += $bet_history['bet_amount'];
        }
        $total_commission_amount = $total_bet_amount * (1 - self::get_commission());
        $total_win_bet_amount = self::calculate_total_win_bet_amount($bet_histories, $bet_history['choice_id']);
        if ($before_betting) {
            $total_win_bet_amount += $bet_history['bet_amount'];
        }
        
        $profit_base_on_1_dola = 0;
        if ($total_win_bet_amount != 0) {
            $profit_base_on_1_dola = $total_commission_amount / $total_win_bet_amount;
        }
        $profit = self::calculate_profit($profit_base_on_1_dola, $bet_history['bet_amount']);
        
        return $profit;
    }
    
    public static function update_affiliate_profit($user_id, $invite_by_user_id) {
        if (!empty($invite_by_user_id) && $invite_by_user_id != -1) {
            $dao_user = new dao_user();
            $bet_history = self::get_bet_history_by_user_id_and_invited_user_id($user_id, $invite_by_user_id);
            $user = $dao_user->get_by_id($user_id);
            $affiliate_profit = self::get_affiliate_commission() * $bet_history['bet_amount'];
            $affiliate_profit += $user['affiliate_profit'];
            $dao_user->update_affiliate_profit($user_id, $affiliate_profit);
        }
    }
    
    public static function get_bet_history_by_user_id_and_invited_user_id($user_id, $invite_by_user_id) {
        $dao_bet_history = new dao_bet_history();
        $dao_user = new dao_user();
        $user = $dao_user->get_by_id($user_id);
        return $dao_bet_history->get_bet_history_by_user_id_and_invited_user_id($user['email'], $invite_by_user_id);
    }
    
    private static function calculate_total_bet_amount($bet_histories) {
        $total = 0;
        foreach ($bet_histories as $item) {
            $total += $item['bet_amount'];
        }
        return $total;
    }
    
    private static function calculate_total_win_bet_amount($bet_histories, $win_choice_id) {
        $total = 0;
        foreach ($bet_histories as $item) {
            if ($item['choice_id'] == $win_choice_id) {
                $total += $item['bet_amount'];
            }
        }
        return $total;
    }
    
    private static function calculate_profit($profit_base_on_1_dola, $win_bet_amount) {
        return $profit_base_on_1_dola * $win_bet_amount - $win_bet_amount;
    }
    
    public static function get_commission() {
        $option = api_general::get_option("commission");
        return $option / 100;
    }
    
    public static function get_affiliate_commission() {
        $option = api_general::get_option("affiliate_commission");
        return $option / 100;
    }
    
}
